/*******************************************************************************
 * File name:     main.c
 * Description:   main file of IEC project
 * Important:     - if testing power failure, remember that power failure priority
 *                needs to be lower than MCI priority
 * Project:       IEC
 * Target:        LPC2478
 * Compiler:      arm-none-eabi-gcc
 * Date:          2010-12-02
 * Author:        Kuba
 * Based on: -
 ******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
# include <stdbool.h>
# include "LPC24xx.h"
# include "typedef.h"
# include "init.h"
# include "irq.h"
# include "board.h"
# include "timer.h"
# include "uart.h"
# include "printf.h"
# include "gpdma.h"
# include "sdram.h"
# include "mci.h"

/*==============================================================================
 Defines
==============================================================================*/
# define MCI_BLOCK_SIZE       512
# define BLOCKS_NUM           32
# define BUFF_SIZE            ((MCI_BLOCK_SIZE * BLOCKS_NUM * 1) + 0)
# define MCI_BYTE2SEND        0x88

# define DMA                  1
/*==============================================================================
 Globals
==============================================================================*/
struct uart u0, u2;
static struct timerConf tmr;
static timer t;

uint8 *xRamTxBuff = (uint8 *)0xA0100000;  /* TX buffer in external SDRAM */
uint8 *xRamRxBuff = (uint8 *)0xA1000000;  /* RX buffer in external SDRAM */
uint8 txBuff[10] = {0x11, 0x22, 0x11, 0x22, 0x11, 0x22, 0x11, 0x22, 0x11, 0x22};
uint8 rxBuff[512] = {0};

/*==============================================================================
 Static ISR prototypes
==============================================================================*/

/*==============================================================================
 Static function prototypes
==============================================================================*/
static void jtagDelay   (void);

static void fillTxBuff  (uint8 *ptr, uint32 size, uint8 pattern);
static void fillRxBuff  (uint8 *ptr, uint32 size, uint8 pattern);
static void memTest     (uint8 *buff1, uint8 *buff2, uint32 size);
static void timerService(void);
/*==============================================================================
 Main function
==============================================================================*/
int main(void)
{
   /* ARM initialization */
   jtagDelay();
   systemInit();
   irqEnableCpsr();

   uint32 i;
   /* peripherals initialization */
   /* leds */
   ledInit();
   /* uart */
   u2.uartNo            = uart2;                /* messages via RS232 */
   u2.baud              = baud9600;
   u2.wordLen           = word8BIT;
   u2.stopBit           = stop1BIT;
   u2.parity            = parityDISABLE;
   u2.paritySel         = parityODD;
   u2.breakCtrl         = breakCTRL_DISABLE;
   u2.fifo              = 0;
   u2.intrpt            = 0;
   u2.intrptTxTrig      = 0;
   u2.intrptRxTrig      = 0;
   u2.buffers.txBuff    = 0;
   u2.buffers.txBuffSize= 0;
   u2.buffers.rxBuff    = 0;
   u2.buffers.rxBuffSize= 0;
   uartInit (&u2);
   uprintf ("%s\n", "*** Hey, MCI! ***");
   /* timer */
   tmr.number = timer0;
   tmr.priority = irqLOWEST_PRIORITY;
   tmr.match[1].interrupt = matchINTERRUPT_ENABLE;
   tmr.match[1].reset = matchRESET_ENABLE;
   tmr.match[1].delay = 72000000;
   tmr.match[1].matchService = timerService;       /* blink led */
   t = timerInit (&tmr);
   timerMatchEnable(t);                            /* timer only for led effects */

   /* external SDRAM init */
   sdram_init();
   //sdramTest();
   /* GPDMA init */
   gpdmaInit(irqHIGHEST_PRIORITY);

   if (mciInit (irqHIGHEST_PRIORITY) == FALSE)
   {
      uprintf("%s\n", "MCI init error");
      while (1);
   }
   /* Card init */
   if (mciCardInit(mciDMA_ENABLE) == FALSE)
   {
      uprintf ("%s\n", "Card init error");
      mciCardInfo();
      while (1);
   }
   mciCardInfo ();                                    /* display card infos */

# if DMA
   /* test DMA support */
   fillTxBuff(xRamTxBuff, BUFF_SIZE, MCI_BYTE2SEND);  /* fill MCI TX buffer */
   fillRxBuff(xRamRxBuff, BUFF_SIZE, 0xFB);

   if (mciDmaWrite2Card(xRamTxBuff, 1, BUFF_SIZE) == -1)    /* write data to card */
   {
      while(1);
   }
   if (mciDmaReadCard(xRamRxBuff, 1, BUFF_SIZE) == -1)    /* read data from card */
   {
      while(1);
   }
   memTest(xRamTxBuff, xRamRxBuff, BUFF_SIZE);

   fillTxBuff(xRamTxBuff, BUFF_SIZE, 0x17);
   fillRxBuff(xRamRxBuff, BUFF_SIZE, 0xFA);
   if (mciDmaWrite2Card(xRamTxBuff, 5, BUFF_SIZE) == -1)    /* write data to card */
   {
      while(1);
   }
   if (mciDmaReadCard(xRamRxBuff, 5, BUFF_SIZE) == -1)    /* read data from card */
   {
      while(1);
   }
   memTest(xRamTxBuff, xRamRxBuff, BUFF_SIZE);
# else
   /* software operation */
   if (mciPrgWrite2Card(txBuff, 2, 1) == -1)
   {
      while(1);
   }
   if (mciPrgReadCard(rxBuff, 2, 1) == -1)
   {
      while(1);
   }
   memTest(txBuff, rxBuff, 10);
# endif

   while (1)
   {
      ledOn(1);
      for (i = 0; i < 5000000; ++i);
      ledOff(1);
      for (i = 0; i < 5000000; ++i);
   }
   return 0;
}

/*==============================================================================
 Static function definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   jtagDelay
 description:     function provides a delay required by jtag
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void jtagDelay (void)
{
   volatile unsigned int i;
   for (i = 0; i < 200000; ++i);
}
# if 0
/*------------------------------------------------------------------------------
 function name:      swiLedOn
 description:     function change led's state via SWI interrupt
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void swiLedOn ()
{
   asm volatile ("swi #1\n\t");
}

/*------------------------------------------------------------------------------
 function name:      swiLedOff
 description:     function change led's state via SWI interrupt
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void swiLedOff ()
{
   asm volatile ("swi #2\n\t");
}
# endif
/*------------------------------------------------------------------------------
 function name:   fillTxBuff
 description:     fill any buffer with pattern
 parameters:      pointer to buffer, size, pattern
 returned value:  none
------------------------------------------------------------------------------*/
static void fillTxBuff (uint8 *ptr, uint32 size, uint8 pattern)
{
   uint32 i;

   for (i = 0; i < size; ++i)
   {
      *(ptr + i) = pattern;   /* NOTE: *(ptr + 256) == 0 */
   }
   *(ptr + 10) = 0xAA;  /* some random values to make test more reliable */
   *(ptr + 50) = 0xBB;
   *(ptr + 105) = 0xCC;
   *(ptr + 1000) = 0x5E;
   *(ptr + 10000) = 0xAF;
}

/*------------------------------------------------------------------------------
 function name:   fillRxBuff
 description:     fill any buffer with pattern
 parameters:      pointer to buffer, size, pattern
 returned value:  none
------------------------------------------------------------------------------*/
static void fillRxBuff (uint8 *ptr, uint32 size, uint8 pattern)
{
   uint32 i;

   for (i = 0; i < size; ++i)
   {
      *(ptr + i) = pattern;   /* NOTE: *(ptr + 256) == 0 */
   }
}
/*------------------------------------------------------------------------------
 function name:   memTest
 description:     test buffers
 parameters:      first pointer to memory, second pointer to memory, size
 returned value:  none
------------------------------------------------------------------------------*/
static void memTest (uint8 *buff1, uint8 *buff2, uint32 size)
{
   uint32 i;

   for (i = 0; i < size; ++i)
   {
      if (buff1[i] != buff2[i])
      {
         uprintf("MCI buffer error at: %d, RX: %x", i, xRamRxBuff[i]);
         while(1);
      }
   }
   uprintf("%s\n", "MCI buffers ok");
}

/*------------------------------------------------------------------------------
 function name:   timerService
 description:
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void timerService (void)
{
   ledBlink(0);          /* change LED pin's state */
}



/******************************************************************************
* END OF FILE
******************************************************************************/
